/*
    This file is part of QTau
    Copyright (C) 2013-2018  Tobias "Tomoko" Platen <tplaten@posteo.de>
    Copyright (C) 2013       digited       <https://github.com/digited>
    Copyright (C) 2010-2013  HAL@ShurabaP  <https://github.com/haruneko>

    QTau is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    SPDX-License-Identifier: GPL-3.0+
*/

#include "tempomap.h"
#include <QJsonObject>

bool indexCompare(const tempoindex &i1, const tempoindex &i2)
 {
     return i1.pos < i2.pos;
 }
void TempoMap::updateIndexList()
{
    qSort(_index.begin(), _index.end(), indexCompare);
}

TempoMap::TempoMap()
{

}

void TempoMap::addTempo(int pos, float tempo)
{
    beginInsertRows(QModelIndex(),1,1);
    _tempo[pos] = tempo;
    tempoindex idx;
    idx.pos = pos;
    idx.type = 0;
    _index.append(idx);
    updateIndexList();
    endInsertRows();
}

void TempoMap::addTimeSignature(int pos, int numerator, int denominator)
{
    beginInsertRows(QModelIndex(),1,1);
    fraction time;
    time.denominator = denominator;
    time.numerator = numerator;
    tempoindex idx;
    idx.pos = pos;
    idx.type = 1;
    _index.append(idx);
    _time[pos] = time;
    updateIndexList();
    endInsertRows();
}

void TempoMap::removeEventAt(int index)
{
    if(index<_index.size() && index>=0)
    {
        beginRemoveRows(QModelIndex(),index,index);
        if(_index[index].type==1)
        {
            _time.remove(_index[index].pos);
        }
        else if(_index[index].type==0)
        {
            _tempo.remove(_index[index].pos);
        }
        _index.removeAt(index);
        endRemoveRows();
    }

}

fraction TempoMap::getTimeSignatureForBar(int pos)
{
    fraction time = _time[pos];
    while(time.denominator==0 && time.numerator==0)
    {
        pos--;
        time = _time[pos];
    }
    return time;
}

QModelIndex TempoMap::index(int row, int column, const QModelIndex &parent) const
{
    Q_UNUSED( parent );
    return createIndex(row,column);
}

QModelIndex TempoMap::parent(const QModelIndex &child) const
{
    Q_UNUSED( child );
    return QModelIndex();
}

int TempoMap::rowCount(const QModelIndex &parent) const
{
   Q_UNUSED( parent );
   return _index.count();
}

int TempoMap::columnCount(const QModelIndex &parent) const
{
    Q_UNUSED( parent );
    return 3;
}

QVariant TempoMap::data(const QModelIndex &index, int role) const
{
    if(role!=Qt::DisplayRole) return QVariant();
    int row = index.row();
    int col = index.column();
    int pos = _index[row].pos;
    int type = _index[row].type;
    if(col==0) return QVariant(pos+1).toString();
    if(col==1)
    {
        if(type==0) return "Tempo";
        if(type==1) return "Time Signature";
    }
    if(col==2)
    {
        if(type==0) return _tempo[pos];
        if(type==1) return QVariant(_time[pos].numerator).toString()+"/"+QVariant(_time[pos].denominator).toString();
    }
    return QVariant();
}

void TempoMap::beginEditing()
{
    _origIndex = _index;
    _origTempo = _tempo;
    _origTime = _time;
}

void TempoMap::toJson(QJsonArray& array)
{
    for(int i=0;i<_index.length();i++)
    {
        int pos = _index[i].pos;
        int type = _index[i].type;
        if(type==1)
        {
            QJsonObject val;
            val["pos"] = pos;
            val["type"] = "timeSig";
            val["denominator"] = _time[pos].denominator;
            val["numerator"] = _time[pos].numerator;
            array.append(val);
        }
        else if(type==0)
        {
            QJsonObject val;
            val["pos"] = pos;
            val["type"] = "tempo";
            val["tempo"] = _tempo[pos];
            array.append(val);
        }
    }
}

void TempoMap::fromJson(QJsonArray &array)
{
    _index.clear();
    _time.clear();
    _tempo.clear();
    for(int i=0;i<array.size();i++)
    {
        QJsonObject val = array[i].toObject();
        if(val["type"].toString()=="timeSig")
        {
           int pos = val["pos"].toInt();
           int denominator = val["denominator"].toInt();
           int numerator = val["numerator"].toInt();
           this->addTimeSignature(pos,numerator,denominator);
        }
        else if(val["type"].toString()=="tempo")
        {
           int pos = val["pos"].toInt();
           int tempo = val["tempo"].toInt();
           this->addTempo(pos,tempo);
        }
    }
}

void TempoMap::undo()
{
    _index = _origIndex;
    _tempo = _origTempo;
    _time = _origTime;
}
